<template>
  <div>
    <!-- 头部面包屑 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>商品管理</el-breadcrumb-item>
      <el-breadcrumb-item>参数列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 卡片视图 -->
    <el-card class="box-card">
      <!-- 警告提示 -->
      <el-alert show-icon :closable="false" title="注意：只允许为第三级分类设置相关属性" type="warning"></el-alert>

      <!-- 级联选择框 -->
      <div class="cascader">
        <span class="demonstration">选择商品分类：</span>
        <el-cascader
          clearable
          v-model="selectKeys"
          :options="cateList"
          :props="cateProps"
          @change="cateChange"
        ></el-cascader>
      </div>

      <!-- tab 选项卡 -->
      <el-tabs v-model="activeName" @tab-click="tabChangeClick">
        <!-- 动态参数 -->
        <el-tab-pane label="动态参数" name="many">
          <!-- 添加按钮 -->
          <el-button
            type="primary"
            size="mini"
            :disabled="this.selectKeys.length !== 3 ? true : false"
            @click="addUpdateParams"
          >添加参数</el-button>
          <!-- 表格 -->
          <el-table :data="manyList" style="width: 100%">
            <!-- 展开列 -->
            <el-table-column type="expand" v-slot="slot">
              <el-tag v-for="(item,index) in slot.row.attr_vals" :key="index" closable @close="handleTagClose(slot.row,item)">{{item}}</el-tag>
              <el-input class="input-new-tag"  v-if="slot.row.inputVisible" v-model="slot.row.inputValue" ref="saveTagInput"
                size="small" @keyup.enter.native="handleInputConfirm(slot.row)" @blur="handleInputConfirm(slot.row)"
              ></el-input>
              <el-button v-else class="button-new-tag" size="small" @click="showInput(slot.row)">+ New Tag</el-button>
            </el-table-column>
            <!-- 索引列 -->
            <el-table-column type="index" label="#"></el-table-column>
            <el-table-column prop="attr_name" label="参数名称"></el-table-column>
            <el-table-column label="操作" v-slot="slot">
              <el-button
                type="primary"
                icon="el-icon-edit"
                @click="editParams(slot.row)"
                size="mini"
              >修改</el-button>
              <el-button
                type="danger"
                icon="el-icon-delete"
                @click="deleteParams(slot.row)"
                size="mini"
              >删除</el-button>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="静态属性" name="only">
          <el-button
            type="primary"
            size="mini"
            :disabled="this.selectKeys.length !== 3 ? true : false"
            @click="addUpdateParams"
          >添加属性</el-button>
          <!-- 表格 -->
          <el-table :data="onlyList" style="width: 100%">
            <!-- 展开列 -->
            <el-table-column type="expand" v-slot="slot">
              <el-tag v-for="(item,index) in slot.row.attr_vals" :key="index" closable @close="handleTagClose(slot.row,item)">{{item}}</el-tag>
              <el-input class="input-new-tag"  v-if="slot.row.inputVisible" v-model="slot.row.inputValue" ref="saveTagInput"
                size="small" @keyup.enter.native="handleInputConfirm(slot.row)" @blur="handleInputConfirm(slot.row)"
              ></el-input>
              <el-button v-else class="button-new-tag" size="small" @click="showInput(slot.row)">+ New Tag</el-button>
            </el-table-column>
            <!-- 索引列 -->
            <el-table-column type="index" label="#"></el-table-column>
            <el-table-column prop="attr_name" label="参数名称"></el-table-column>
            <el-table-column label="操作">
              <template v-slot="slot">
                <el-button
                  type="primary"
                  icon="el-icon-edit"
                  @click="editParams(slot.row)"
                  size="mini"
                >修改</el-button>
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  @click="deleteParams(slot.row)"
                  size="mini"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>

      <!-- 添加弹框 -->
      <el-dialog
        @close="resetAddUpdateForm"
        :title="addEdit + titleText"
        :visible.sync="addUpdateVisiable"
      >
        <el-form
          :model="addUpdateForm"
          :rules="addUpdateRules"
          ref="addUpdateForm"
          label-width="100px"
        >
          <el-form-item :label="titleText" prop="attr_name">
            <el-input v-model="addUpdateForm.attr_name"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="addUpdateVisiable = false">取 消</el-button>
          <el-button type="primary" @click="addUpdateSubmit">确 定</el-button>
        </span>
      </el-dialog>
    </el-card>
  </div>
</template>
<script>
import {
  reqAllCateList,
  reqParamsList,
  reqAddParams,
  reqEditParams,
  reqDeleteParams,
  reqAddOptionalParams
} from "../../api/index";
export default {
  data() {
    return {
      // 所有的分类数据
      type: 3,
      // 分类的id
      selectKeys: [],
      // 所有商品列表的数据
      cateList: [],

      // 级联选择器的配置项
      cateProps: {
        expandTrigger: "hover",
        value: "cat_id",
        label: "cat_name",
        children: "children"
      },

      // tab 选中项
      activeName: "many",

      // 动态属性
      manyList: [],

      //  静态方法
      onlyList: [],

      // 弹框
      addUpdateVisiable: false,

      // 表单的数据
      addUpdateForm: {
        attr_name: ""
      },

      // 表单的验证规则
      addUpdateRules: {
        attr_name: [{ required: true, message: "请输入内容", trigger: "blur" }]
      },

      // 判断是添加还是编辑
      attr_id: "",
    };
  },

  methods: {
    // 获取所有的分类列表
    async getCateList() {
      const result = await reqAllCateList(this.type);
      if (result.meta.status === 200) {
        this.cateList = result.data;
      } else {
        this.$message.error(result.meta.msg);
      }
    },

    // 级联选择框change的函数
    cateChange() {
      if (this.selectKeys.length !== 3) {
        this.selectKeys = [];
        this.manyList = []
        this.onlyList = []
        return;
      }
      console.log(this.selectKeys);
      this.getPropsList();
    },

    // 切换选项卡
    tabChangeClick(tab) {
      console.log(this.activeName);
      this.getPropsList();
    },

    // 获取分类动态参数或静态属性的函数
    async getPropsList() {
      const id = this.selectKeys[this.selectKeys.length - 1];
      const result = await reqParamsList(id, this.activeName);

      // 将字符串转成数组存储起来
      result.data.forEach(item => {
        item.attr_vals = item.attr_vals ? item.attr_vals.split(" ") : []

        // 给每一个遍历的tag元素都加上唯一的是否显示input，input的值
        // tag 中 input 与 button 的切换
        item.inputVisible = false
        // tag 中 input 输入的值
        item.inputValue = ''
      })

      if (result.meta.status === 200) {
        if (this.activeName === "many") {
          this.manyList = result.data;
          // console.log(this.manyList);
        } else {
          this.onlyList = result.data;
          // console.log(this.onlyList);
        }
      } else {
        this.$message.error(result.meta.msg);
      }
    },

    // 编辑动态参数
    editParams(params) {
      this.attr_id = params.attr_id;
      this.addUpdateForm.attr_name = params.attr_name;
      this.addUpdateVisiable = true;
    },

    // 删除参数
    deleteParams(params) {
      this.$confirm(`您确定要删除 【${params.attr_name}】 吗?`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(async () => {
          const result = await reqDeleteParams(params.cat_id, params.attr_id);
          if (result.meta.status === 200) {
            this.$message.success("删除成功!");
            this.getPropsList();
          } else {
            this.$message.error(result.meta.msg);
          }
        })
        .catch(err => err);
    },

    // 重置表单的信息
    resetAddUpdateForm() {
      this.attr_id = "";
      this.addUpdateForm.attr_name = "";
    },

    // 添加修改弹框
    addUpdateParams() {
      this.attr_id = "";
      this.addUpdateVisiable = true;
    },

    // 表单的同一验证
    addUpdateSubmit() {
      this.$refs.addUpdateForm.validate(async valid => {
        if (!valid) return;
        const id = this.selectKeys[this.selectKeys.length - 1];
        // 添加
        if (!this.attr_id) {
          const result = await reqAddParams(
            id,
            this.addUpdateForm.attr_name,
            this.activeName
          );
          if (result.meta.status === 201) {
            this.$message.success("添加参数成功");
            this.getPropsList();
          } else {
            this.$message.error(result.meta.msg);
          }
          // 弹框消失
          this.addUpdateVisiable = false;
        } else {
          // 编辑
          const result = await reqEditParams(
            id,
            this.attr_id,
            this.addUpdateForm.attr_name,
            this.activeName
          );
          console.log(result);
          if (result.meta.status === 200) {
            this.$message.success("更新参数成功");
            this.getPropsList();
          } else {
            this.$message.error(result.meta.msg);
          }
          // 弹框消失
          this.addUpdateVisiable = false;
        }
      });
    },

    // tag 的 input 按下或失去焦点触发的函数
    async handleInputConfirm(row) {

        if (row.inputValue.trim()){
          row.attr_vals.push(row.inputValue)
          this.updateParams(row)
        }
        row.inputVisible = false
        row.inputValue = ''
      },

    // tag 的 input 点击关闭按钮
    handleTagClose(row,deleteItem){
      row.attr_vals.splice(row.attr_vals.indexOf(deleteItem),1)
      this.updateParams(row)
    },

    // 保存参数的函数，可以直接调用
      async updateParams(row){
          const result = await reqAddOptionalParams(row.cat_id,row.attr_id,row.attr_name,row.attr_sel,row.attr_vals.join(' '))
          this.inputValue = ''
          if (result.meta.status === 200) {
            this.$message.success("更新参数成功")
          } else {
            this.$message.error(result.meta.msg);
          }
      },
    
    // 点击按钮显示input
    showInput(row){
       row.inputVisible = true;
      //  光标自动聚焦
        this.$nextTick(_ => {
          this.$refs.saveTagInput.$refs.input.focus();
        })
    },
  },

  computed: {
    titleText() {
      if (this.activeName === "many") {
        return "动态参数";
      }
      return "静态属性";
    },

    addEdit() {
      if (!this.attr_id) {
        return "添加";
      }
      return "修改";
    }
  },

  created() {
    this.getCateList();
  }
};
</script>

<style lang="less" scoped>
.el-card {
  margin-top: 15px;

  .cascader {
    margin-top: 20px;

    .el-cascader {
      width: 50%;
    }
  }

  .el-tabs {
    margin-top: 30px;
    width: 98%;
    height: 100%;
  }

  .el-tag {
    margin: 0 0 10px 10px;
  }
  .button-new-tag {
    margin-left: 10px;
    height: 32px;
  }
  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: center;
  }
}

/* 
1. 级联选择框只能选中三级分类，不能选中一级和二级分类
通过 Cascader 的change事件得到的数组来判断，如果长度不等于3，怎清空绑定的数组
cateChange(){
    if(this.selectKeys.length !== 3){
        this.selectKeys = []
    }
    console.log(this.selectKeys)
},


2. tabs标签页的使用
v-model="activeName" 实现双向数据绑定，将当前el-tab-pane中激活的name绑定到属性上
@tab-click="handleClick"  点击tab标签会触发的事件处理函数
label="用户管理"  用来显示页签的table标题
name="first"  给页签指定唯一的名称，此名称会绑定到el-tabs的v-model上
<el-tabs v-model="activeName" @tab-click="handleClick">
    <el-tab-pane label="用户管理" name="first">用户管理</el-tab-pane>
    <el-tab-pane label="配置管理" name="second">配置管理</el-tab-pane>
    <el-tab-pane label="角色管理" name="third">角色管理</el-tab-pane>
    <el-tab-pane label="定时任务补偿" name="fourth">定时任务补偿</el-tab-pane>
  </el-tabs>

3. 按钮是否可以启用，可以通过级联选择框中的数组是否为3，如果是3，启动按钮，如果不是3，禁用

4. 发送参数列表的请求  categories/:id/attributes
此处的 id 是指三级列表的id，需要通过判断来获取，如果数组!==3,返回null；如果数组为3，返回最后一个值

5. 处理切换tab不发起请求的bug，将发请求的代码抽离到另外的函数中，无论点击级联选择器还是tab都需要重新调用该函数

6. 点击tab获取到的静态数据和动态数据需要做区分，做判断并且将这两个数据需要放到不同的属性中



================================================================
渲染参数下的可选项
attr_vals 是服务器返回的数据，是字符串，每个可选项之间都是用空格进行分割的，
如果要将可选项渲染为标签，需要将字符串用空格进行分割，分割后形成数组，再对数组进行遍历来渲染tag标签
注：需要先分割再进行manyList或onlyList的赋值，这样可以直接变成数组
 res.data.forEach(item => {
        item.attr_vals = item.attr_vals.split(' ') : []
        // 控制文本框的显示与隐藏
        item.inputVisible = false
      })


解决不填文字但会出现tag的bug，''.splice(' ') = [""]需要先对item.attr_vals做判断，再进行分割
res.data.forEach(item => {
        item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
        // 控制文本框的显示与隐藏
        item.inputVisible = false
      })



=====================================================
控制文本框和按钮的切换显示
1. input 和 button 上有 v-if 或 v-else 属性
2. input 的 v-model，将自身的值双向绑定 
3. ref 是 input 的引用对象
4. @keyup.enter.native 按键抬起事件
5. @blur 失去焦点事件
<el-input
  class="input-new-tag"
  v-if="inputVisible"
  v-model="inputValue"
  ref="saveTagInput"
  size="small"
  @keyup.enter.native="handleInputConfirm"
  @blur="handleInputConfirm"
>
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button>
 data() {
      return {
        inputVisible: false,
        inputValue: ''
      };
    },
methods: {
    handleInputConfirm() {
    let inputValue = this.inputValue;
    if (inputValue) {
        this.dynamicTags.push(inputValue);
    }
    this.inputVisible = false;
    this.inputValue = '';
    }
}

出现的bug，第一个input填入值，下层的input有相同的值，需要修改遍历tag的函数，增加【控制文本框的显示与隐藏 和 设置文本框中输入的值为空】，同时需要修改input的组件内容，使得每次修改只改自己的内容 （每一行都有input都有自己的显示隐藏 和 文本框的输入内容
v-if="scope.row.inputVisible" v-model="scope.row.inputValue"

res.data.forEach(item => {
        item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
        // 控制文本框的显示与隐藏
        item.inputVisible = false
        // 文本框中输入的值
        item.inputValue = ''
      })

 <!-- 循环渲染Tag标签 -->
<!-- 输入的文本框 -->
<el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)">
</el-input>

@click="showInput(scope.row)
<el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>


=================================================================
让文本框自动获取焦点
showInput(row) {
    row.inputVisible = true ----------此时显示的是button，不是input
    // 让文本框自动获得焦点
    // $nextTick 方法的作用，就是当页面上元素被重新渲染之后，才会指定回调函数中的代码
    this.$nextTick(_ => {
    this.$refs.saveTagInput.$refs.input.focus()
    })
},

==================================================================
处理 input 失去焦点的时候自动变成按钮
处理 input 输入很多空格，但又失去焦点应该将input的值置为空
async handleInputConfirm(row) {
      if (row.inputValue.trim().length === 0) {
        row.inputValue = ''
        row.inputVisible = false
        return
      }
      // 如果没有return，则证明输入的内容，需要做后续处理
      row.attr_vals.push(row.inputValue.trim())
      row.inputValue = ''
      row.inputVisible = false
      // 需要发起请求，保存这次操作
      this.saveAttrVals(row)
    },

*/
</style>